#include <iostream>
#include "socket.hpp"
#include <poll.h>
#include <sys/time.h>

const int fd_num_max = 64;
const uint16_t default_fd = -1; // 将所有需要管理的文件描述符放入一个数组，-1是数组中的无效元素
int non_event = 0;

class PollServer
{
public:
	// 构造函数
	PollServer(uint16_t port = default_fd)
		: _port(port)
	{
		// 初始化数组
		for (int i = 0; i < fd_num_max; i++)
		{
			_event_fds[i].fd = default_fd;
			_event_fds[i].events = non_event;
			_event_fds[i].revents = non_event;
		}
	}

	// 初始化
	void Init()
	{
		_listensock.Socket();
		_listensock.Bind(_port);
		_listensock.Listen();
	}

	// 处理客户端发来的链接请求
	void Accepter()
	{
		// 客户端发来请求，建立链接
		string clienttip;
		uint16_t clientport = 0;
		int sock = _listensock.Accept(clienttip, clientport);
		if (sock < 0)
		{
			cout << "Accepter false" << endl;
			return;
		}

		cout << "Accepter success,sock: " << sock << endl;
		
		int pos = 1;
		for (; pos < fd_num_max; pos++)
		{
			// 找到数组中没有，放入文件描述符的位置
			if (_event_fds[pos].fd != default_fd)
				continue;
			else
				break;
		}
		// 数组中文件描述符存满了
		if (pos == fd_num_max)
		{
			cout << "server is full" << endl;
			close(sock);
		}
		else
		{
			_event_fds[pos].fd = sock;
            _event_fds[pos].events = POLLIN;
            _event_fds[pos].revents = non_event;
            PrintFd();
		}
	}

	// 处理客户端发来的信息
	void Recver(int fd, int pos)
	{
		// 用来存储客户端发来的数据
		char buffer[1024];
		ssize_t n = read(fd, buffer, sizeof(buffer) - 1); // 最后一个换行符不要
		if (n > 0)
		{
			buffer[n] = 0;
			cout << "get a messge: " << buffer << endl;
		}
		else if (n == 0)
		{
			cout << "client quit,me too" << endl;
			close(fd);
			// 由于客户端退出了，即该文件描述符不需要被poll监听，即将其关闭
			_event_fds[pos].fd = default_fd; 
		}
		else
		{
			cout << "read false" << endl;
			close(fd);
			_event_fds[pos].fd = default_fd; 
		}
	}


	void Hander()
    {
        for (int i = 0; i < fd_num_max; i++) 
        {
            int fd = _event_fds[i].fd;
            if (fd == default_fd)
                continue;

            if (_event_fds[i].revents & POLLIN)
            {
                if (fd == _listensock.Getlistensockfd())
                {
                    Accepter(); // 连接管理器
                }
                else 
                {
                    Recver(fd, i);
                }
            }
        }
    }

	// 启动服务器
	void Start()
	{
		_event_fds[0].fd = _listensock.Getlistensockfd();
		_event_fds[0].events = POLLIN;
		int timeout = 3000; // 3s
		while (true)
		{
			int n = poll(_event_fds, fd_num_max, -1); 
			switch (n)
			{
			case 0:
				cout << "time out" << endl;
				break;
			case -1:
				cout << "poll false" << endl;
				break;
			default:
				cout << "get a new link!!" << endl;
				Hander(); 
				break;
			}
			sleep(3);
		}
	}

	// 打印
	void PrintFd()
	{
		cout << "online fd list: ";
		for (int i = 0; i < fd_num_max; i++)
		{
			if (_event_fds[i].fd == default_fd)
				continue;
			cout << _event_fds[i].fd << " ";
		}
		cout << endl;
	}

	// 析构函数
	~PollServer()
	{
		_listensock.Close();
	}

private:
	uint16_t _port;	  // 端口号
	Sock _listensock; // 套接字
	struct pollfd _event_fds[fd_num_max];
};